#!/bin/bash#######################
#                 _       _      # #
#   ___ _____ ___| |_ ___| |_    #   #
#  |_ -|     | .'|  _|  _|   |   #     #
#  |___|_|_|_|__,|_| |___|_|_|   #       #
#  ~~~~~~~~~~Ver. 1~~~~~~~~~~~   #_________#
#  Compare a private key, certificate and  #
#   CSR (optional), to ensure they match   #
#  before installation.  -- By Gary Locke  #
############################################

# In Living Color.
RED="\033[1;31m"
GREEN="\033[1;32m"
COLOR_RESET="\033[0m"

# Function junction.
printhash() {
echo -e "${GREEN}${KEY_HIGHLIGHT}${K_HASH} ${COLOR_RESET}${KEY}"
echo -e "${GREEN}${CRT_HIGHLIGHT}${C_HASH} ${COLOR_RESET}${CRT}"
if [[ "$CHECK_CSR" == 1 ]];then
    echo -e "${GREEN}${CSR_HIGHLIGHT}${R_HASH} ${COLOR_RESET}${CSR}"
fi
}

good_result() {
echo -e "\n${GREEN}Good! ${COLOR_RESET}- No mismatches found.\n"
}

full_compare() {
if ( [[ "$RK_MISMATCH" == 1 ]] && [[ "$RC_MISMATCH" == 1 ]] && [[ "$KC_MISMATCH" == 0 ]] ); then
    echo -e "\n${RED}CSR does not match!${COLOR_RESET}\n"
    CSR_HIGHLIGHT=$RED && printhash
    exit 1
elif ( [[ "$RK_MISMATCH" == 1 ]] && [[ "$RC_MISMATCH" == 0 ]] && [[ "$KC_MISMATCH" == 1 ]] ); then
    echo -e "\n${RED}Private key does not match!${COLOR_RESET}\n"
    KEY_HIGHLIGHT=$RED && printhash
    exit 1
elif ( [[ "$RK_MISMATCH" == 0 ]] && [[ "$RC_MISMATCH" == 1 ]] && [[ "$KC_MISMATCH" == 1 ]] ); then
    echo -e "\n${RED}Certificate does not match!${COLOR_RESET}\n"
    CRT_HIGHLIGHT=$RED && printhash
    exit 1
else
    good_result && exit 0
fi
}

do_compare() {
if [[ "$CHECK_CSR" == 1 ]];then
    full_compare
elif [[ "$KC_MISMATCH" == 1 ]]; then
    echo -e "\n${RED}Private key does not match certificate!${COLOR_RESET}\n"
    KEY_HIGHLIGHT=$RED && CRT_HIGHLIGHT=$RED && printhash
    exit 1
else
    good_result && exit 0
fi
}

# Read in paths to SSL files.
while true;do
    read -e -p "Enter path to private key: " KEY
    if [[ -n "$KEY" ]];then
        if [[ ! -e "$KEY" ]];then
            echo -e "Never heard of it..."
        else
            if openssl rsa -noout -modulus -in $KEY 1>/dev/null 2>&1;then
                break
            else
                echo "Invalid private keyfile."
            fi
        fi
    fi
done
while true;do
    read -e -p "Enter path to certificate: " CRT
    if [[ -n "$CRT" ]];then
        if [[ ! -e "$CRT" ]];then
            echo -e "Never heard of it..."
        else
            if openssl x509 -noout -modulus -in $CRT 1>/dev/null 2>&1;then
                break
            else
                echo "Invalid certificate file."
            fi
        fi
    fi
done
while true;do
    read -e -p "Enter path to CSR (leave blank to skip): " CSR
    if [[ ! -z "$CSR" ]];then
        if [[ ! -e "$CSR" ]];then
            echo -e "Never heard of it..."
        else
            if openssl req -noout -modulus -in $CSR 1>/dev/null 2>&1;then
                CHECK_CSR=1
                break
            else
                echo "Invalid certificate file."
            fi
        fi
    else
        echo -e "Continuing without CSR comparison..."
        break
    fi
done

# Not currently used (as of Ver. 1).
K_BASE=`basename $KEY`
C_BASE=`basename $CRT`
if [[ "$CHECK_CSR" == 1 ]];then
    R_BASE=`basename $CSR`
fi

# deadbeef and hash potatoes.
K_HASH=`openssl rsa -noout -modulus -in $KEY 2>/dev/null| openssl md5|awk '{print $2}'`
C_HASH=`openssl x509 -noout -modulus -in $CRT 2>/dev/null | openssl md5|awk '{print $2}'`
R_HASH=`openssl req -noout -modulus -in $CSR 2>/dev/null| openssl md5|awk '{print $2}'`

# This stuff should be in the function itself.
RC_MISMATCH=0
KC_MISMATCH=0
RK_MISMATCH=0
if [[ ! "$R_HASH" == "$C_HASH" ]]; then
    RC_MISMATCH=$[RC_MISMATCH+1];fi
if [[ ! "$K_HASH" == "$C_HASH" ]]; then
    KC_MISMATCH=$[KC_MISMATCH+1];fi
if [[ ! "$R_HASH" == "$K_HASH" ]]; then
    RK_MISMATCH=$[RK_MISMATCH+1];fi
do_compare

# GTFO
printf "\n${RED}If you can read this, something is wrong with the script.${COLOR_RESET}\n"
exit 1
